﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.NetworkAnalyst;
using Entity;
namespace Utilities
{
    public class EsriUtility
    {
       
        public static void InitEsriLicense()
        {
            LicenseInitializer m_AOLicenseInitializer;
            if (!ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine))
            {
                if (!ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop))
                {
                    //MessageBox.Show("This application could not load the correct version of ArcGIS.");
                    return;
                }
            }

            m_AOLicenseInitializer = new LicenseInitializer();
            if (!m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeArcView, esriLicenseProductCode.esriLicenseProductCodeArcEditor, esriLicenseProductCode.esriLicenseProductCodeArcInfo },
            new esriLicenseExtensionCode[] { esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork }))
            {
                //MessageBox.Show(m_AOLicenseInitializer.LicenseMessage());
                //MessageBox.Show("This application could not initialize with the correct ArcGIS license and will shutdown.");
                m_AOLicenseInitializer.ShutdownApplication();
                return;
            }
        }
        public static IGeoProcessorResult RunTool(Geoprocessor geoprocessor, IGPProcess process, ITrackCancel TC)
        {            
            IGeoProcessorResult GPResult = null;//返回工具箱的执行结果            
            geoprocessor.OverwriteOutput = true;
            // Execute the tool            
            try
            {
                GPResult = geoprocessor.Execute(process, null) as IGeoProcessorResult;
                //if (GPResult.Status != ESRI.ArcGIS.esriSystem.esriJobStatus.esriJobSucceeded)                
                ReturnMessages(geoprocessor);

            }
            catch (Exception err)
            {
                LogManager.appendLine(err.Message);
                ReturnMessages(geoprocessor);
            }
            return GPResult;//返回工具箱的执行结果
        }

        // Function for returning the tool messages.
        private static void ReturnMessages(Geoprocessor gp)
        {
            string message = string.Empty;
            if (gp.MessageCount > 0)
            {
                for (int Count = 0; Count <= gp.MessageCount - 1; Count++)
                {
                    LogManager.appendLine(gp.GetMessage(Count));                    
                }
                
            }

        }
        //保存图层到磁盘中
        public static void SaveLayerToDisk(ILayer layer, String path)
        {
            try
            {
                LogManager.appendLine("Writing layer file containing analysis to " + path);
                ILayerFile layerFile = new LayerFileClass();
                layerFile.New(path);
                layerFile.ReplaceContents(layer as ILayer);
                layerFile.Save();
                LogManager.appendLine("Writing layer file successfully saved");
            }
            catch (Exception err)
            {
                // Write out errors
                LogManager.appendLine(err.Message);
            }
        }
        public static IPoint PCS2GCS(double x, double y)
        {
            IPoint pPoint = new PointClass();
            pPoint.PutCoords(x, y);
            ISpatialReferenceFactory pSRF = new SpatialReferenceEnvironmentClass();           
            pPoint.SpatialReference = pSRF.CreateProjectedCoordinateSystem(32650);
            //32650是在调试过程中，查看SpatialReference属性的factoryCode得来            
            pPoint.Project(pSRF.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984));
            return pPoint;
        }

        public static Collection<ERouteNode> GetNodes(IFeatureClass routeFC)
        {
            IFeatureCursor pFeatureCursor;
            IFeature lineFeature;
            IPointCollection pointCollection;

            Collection<ERouteNode> nodes = new Collection<ERouteNode>();

            pFeatureCursor = routeFC.Search(null, false);
            lineFeature = pFeatureCursor.NextFeature();
            pointCollection = lineFeature.Shape as IPointCollection;

            for (int i = 0; i < pointCollection.PointCount; i++)
            {
                IPoint point = new PointClass();

                IZAware zAware = point as IZAware;
                zAware.ZAware = true;

                pointCollection.QueryPoint(i, point);
                IPoint poiPrj = EsriUtility.PCS2GCS(point.X, point.Y);
                ERouteNode node = new ERouteNode(poiPrj.X, poiPrj.Y, point.Z);
                nodes.Add(node);
            }
            return nodes; 
        }
        
        public static double GetDistanceBetween(IPoint point1, IPoint point2)
        {
            return Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y));
        }
        
    }
}
